package com.thz.admin.handler;

import com.thz.common.exception.BusinessException;
import com.thz.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.ClientAbortException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.io.IOException;

/**
 * 全局异常处理器
 * 
 * @author THZ
 * @date 2025
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    
    /**
     * 业务异常处理
     */
    @ExceptionHandler(BusinessException.class)
    public Result<Void> handleBusinessException(BusinessException e) {
        // 对于格式错误，使用 warn 级别，其他使用 error 级别
        if (e.getMessage() != null && e.getMessage().startsWith("格式错误")) {
            log.warn("文件格式验证失败: {}", e.getMessage());
        } else {
            log.error("业务异常: {}", e.getMessage());
        }
        return Result.error(e.getCode(), e.getMessage());
    }
    
    /**
     * 文件上传大小超限异常处理
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public Result<Void> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        log.error("文件上传大小超限", e);
        return Result.error("文件大小超过限制，请上传小于100MB的文件");
    }
    
    /**
     * 客户端中断连接异常处理
     * 当客户端在服务器响应过程中断开连接时抛出，这是正常情况，不应该记录为错误
     */
    @ExceptionHandler(ClientAbortException.class)
    public void handleClientAbortException(ClientAbortException e) {
        // 客户端中断连接是正常情况，只记录debug日志，不返回响应
        log.debug("客户端中断连接", e);
        // 不返回任何响应，因为连接已经断开
    }
    
    /**
     * 客户端中断连接的IOException处理
     * 处理各种形式的客户端中断连接异常
     */
    @ExceptionHandler(IOException.class)
    public void handleIOException(IOException e) {
        // 检查是否是客户端中断连接
        String message = e.getMessage();
        if (message != null && (
            message.contains("你的主机中的软件中止了一个已建立的连接") ||
            message.contains("Broken pipe") ||
            message.contains("Connection reset") ||
            message.contains("Connection reset by peer"))) {
            // 客户端中断连接，只记录debug日志
            log.debug("客户端中断连接: {}", message);
            // 不返回任何响应
        } else {
            // 真正的IO错误，记录为错误
            log.error("IO异常", e);
        }
    }
    
    /**
     * 响应状态异常处理
     * 当尝试在响应已提交后操作响应时抛出
     */
    @ExceptionHandler(IllegalStateException.class)
    public void handleIllegalStateException(IllegalStateException e) {
        // 检查是否是响应流已使用的异常
        String message = e.getMessage();
        if (message != null && (
            message.contains("getOutputStream() has already been called") ||
            message.contains("getWriter() has already been called") ||
            message.contains("response has already been committed"))) {
            // 响应流冲突，通常是客户端中断导致的，记录debug日志
            log.debug("响应状态异常（通常是客户端中断导致的）: {}", message);
            // 不返回任何响应
        } else {
            // 其他IllegalStateException，记录为错误
            log.error("状态异常", e);
        }
    }
    
    /**
     * HTTP方法不支持异常处理
     * 当使用不支持的HTTP方法请求端点时抛出
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result<Void> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        // 记录警告而不是错误，因为这通常是前端配置问题或浏览器自动请求
        log.warn("HTTP方法不支持: 请求方法={}, 支持的方法={}, 请求路径可能为: {}", 
                e.getMethod(), 
                e.getSupportedMethods() != null ? String.join(", ", e.getSupportedMethods()) : "未知",
                e.getMessage());
        return Result.error("请求方法不支持，请检查API调用方式");
    }
    
    /**
     * 通用异常处理
     */
    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception e) {
        log.error("系统异常", e);
        return Result.error("系统异常: " + e.getMessage());
    }
}




